#!/usr/bin/env python
# -*- coding: UTF-8 -*-
'''
Author: LDW0331 2061278380@qq.com
Date: 2024-03-29 09:41:04
LastEditors: LDW0331 2061278380@qq.com
LastEditTime: 2024-05-16 11:41:59
FilePath: /hrg_bee_dev_v3/src/network_module/ros_app_flask_bridge/scripts/http_server_node.py
Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
'''


import os,subprocess
import rospy
from std_msgs.msg import Bool
from flask import Flask
from gevent import pywsgi

from tool import get_extract_ip,Log_Parser

# from blueprint import *
from blueprint.blueprint_account import account_parser,account_server
from blueprint.blueprint_map import map_parser,map_server
from blueprint.blueprint_task import task_parser,task_server
from blueprint.blueprint_robot import robot_parser,robot_server
from blueprint.blueprint_cmdvel import cmdvel_parser,cmdvel_server
from blueprint.blueprint_bulkdata import bulkdata_parser,bulkdata_server
from blueprint.blueprint_hardware import hardware_parser,hardware_server
from blueprint.blueprint_navgation import navgation_parser,navgation_server
from blueprint.blueprint_opencv import opencv_server
from blueprint.blueprint_ota import ota_parser,ota_server

# 首先进行猴子补丁，使标准库支持异步
# monkey.patch_all()

log = Log_Parser()
class Http_Server_Node:
    def __init__(self, node_name, port):
        self.__node_name = node_name
        self.__processID = os.getpid()
        self.__port = port
        self.__ip ='0.0.0.0'
        
        self.__get_ip = get_extract_ip.extract_ip()
        
        self.__flask_app = Flask(__name__)

        rospy.init_node(self.__node_name, disable_signals=True)
        rospy.on_shutdown(self.Shutdown)
    
    def RegisterBlueprint(self, blueprint_list):
        '''
        注册蓝图
        '''
        for blueprint in blueprint_list:
            self.__flask_app.register_blueprint(blueprint)
            # rospy.loginfo("[{}]Register flask blueprint: {}".format(self.__node_name, blueprint.name))

    
    def StartServer(self):
        '''
        启动服务
        '''
        
        rospy.loginfo("[{}]Starting server: [{}:{}]".format(self.__node_name,self.__ip, self.__port))
        try:
            # 支持多线程    
            self.__flask_app.run(host=self.__ip,port= self.__port,threaded=True)        
           
            # 但线程异步 
            # self.__server = pywsgi.WSGIServer((self.__ip, self.__port), self.__flask_app)
            # self.__server.serve_forever(self)
        except KeyboardInterrupt:
            raise

        

    def StartRunning(self, blueprint_config):
        # rospy.loginfo("[{}]Start running...".format(self.__node_name))

        # 新增等待地图缓存数据加载后再启动
        for i in range(10):
            try:
                state_msg = rospy.wait_for_message("/map_cache_load_state", Bool, timeout=1)
                if state_msg.data:
                    rospy.loginfo("Detect the map loaded.")
                    break
                rospy.sleep(rospy.Duration(0.1))
            except Exception as error:
                print(error)
                pass

        blueprint = []
        
        for config_name, parser_server_tuple in [
            ("account", (account_parser, account_server)),
            ("map", (map_parser, map_server)),
            ("task", (task_parser, task_server)),
            ("robot", (robot_parser, robot_server)),
            ("cmdvel", (cmdvel_parser, cmdvel_server)),
            ("bulkdata", (bulkdata_parser, bulkdata_server)),
            ("hardware", (hardware_parser, hardware_server)),
            ("navgation", (navgation_parser, navgation_server)),
            ("ota", (ota_parser, ota_server)),
            ("opencv", (None, opencv_server))
        ]:
            parser, server = parser_server_tuple
            if blueprint_config[config_name]:
                if parser:
                    parser.InitParser(self.__node_name)
                blueprint.append(server)
                # rospy.loginfo("[{}]Add blueprint {}...".format(self.__node_name, config_name))
                print("[{}]Add blueprint {}...".format(self.__node_name, config_name))
        self.RegisterBlueprint(blueprint)
        self.StartServer()
   
    '''
        节点关闭操作
    '''
    def Shutdown(self):
        # rospy.loginfo("[{}]Stopping the node...".format(self.__node_name))
        subprocess.call(["kill", "-9", str(self.__processID)])

    '''
        获取默认蓝图开关配置
    '''
    def GetDefaultBlueprintConfig(self):
        blueprint_config = {}
        blueprint_config["account"] = True
        blueprint_config["map"] = True
        blueprint_config["task"] = True
        blueprint_config["robot"] = True
        blueprint_config["cmdvel"] = True
        blueprint_config["bulkdata"] = False
        blueprint_config["hardware"] = True
        blueprint_config["navgation"] = True
        blueprint_config["opencv"] = True
        blueprint_config["ota"] = True
        return blueprint_config